package wge

import (
	"net/http"
	"log"
	"sync"
	"os"
	"os/signal"
)

// 一个简单的web服务器游戏引擎

/*	工作流程
	接到请求->调用中间件（可有多个）->路由匹配->调用相应处理方法->返回处理结果
*/

// 网络请求处理函数，返回一个 Stringer 接口
type Handler	func(*Context) Stringer

type wge struct {
	Router
	Server
	handlers	[]Handler
	action		Handler
}

var mu sync.Mutex
var isStarted = false

// 创建一个新的服务器
func NewServer() *wge {
	r := createRouter()
	g := &wge{r, &server{}, nil, nil}
	g.Use(Logger)
	g.Use(Recovery)
	g.action = r.Handle
	
	return g
}

// 添加中间件（过滤器）
func (g *wge) AddMiddleware(h ...Handler) {
	g.handlers = append(g.handlers, h...)
}

// 创建上下文对象
func (g *wge) createContext(w http.ResponseWriter, r *http.Request) *Context {
	r.ParseForm()
	c := &Context{}
	c.w = w
	c.Req = r
	c.Data = r.Form
	c.handlers = g.handlers
	c.action = g.action
	
	return c
}

func (g *wge) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	g.createContext(w, r).run()
}

// 添加一个中间处理器
func (g *wge)Use(h Handler) {
	g.handlers = append(g.handlers, h)
}

func (g *wge)Run() {
	g.RunOnHost("localhost:3000")
}

func (g *wge)RunOnHost(host string){
	mu.Lock()
	if isStarted {
		log.Println("server had started!")
		mu.Unlock()
		return
	}
	isStarted = true
	mu.Unlock()
	logger.Println("server on ", host)
	err := g.Serve(host, g)
	logger.Println(err)
	mu.Lock()
	isStarted = false
	mu.Unlock()
}

var ig = NewServer()

func AddMethod(name string, h ...Handler) {
	ig.AddMethod(name, h...)
}

func AddMiddleware(h ...Handler) {
	ig.AddMiddleware(h...)
}

func Use(h Handler) {
	ig.Use(h)
}

func RunOnHost(host string){
	ig.RunOnHost(host)
}

func Close() error {
	return ig.Close()
}

func ListenClose() {
	ch := make(chan os.Signal)
	signal.Notify(ch, os.Interrupt, os.Kill)
	logger.Println(<- ch)

	server.Close()
}

func SetLogger(l *log.Logger) {
	logger = l
}

func IsStarted() bool {
	return isStarted
}
